//////////////////////////////////////////////
////file: dec.v
////Author: Qyw
////Description: bit decoder module
/////////////////////////////////////////////////
module dec(
			//input
			clk_1m,
			rst_n,
			oe,
			rxd,
			mode,
			cnt,
			active,
			check_stage,
			any_edge,
			car_L2H,
			//output
			data_val,
			cnt_clr,
			dec_en,
			data
			);

input		clk_1m;	 //1M clock singal		
input 		rst_n;	//async reset signal, low is active
input		car_L2H; //carrier pos edge
input		active; //cnt active
input		check_stage; //check stage
input 		mode; //mode singal 1 is 128bits, 0 is 64bits
input 		rxd; //data in singal;
input 		any_edge; //any edge of the din;
input		oe; //oe singal
input	[5:0]		cnt; //carrier cnt

output 		data_val;	//data valid
output  	data;	//data out
output		cnt_clr;
output		dec_en;

wire		half_bit,
			//one_bit,
			quarter_bit,
			stSYNC,
			//stDATA_BEGIN,
			stIDLE,
			stDATA,
			en_sig;

reg		[1:0]	buff,
				state,
				nstate;

parameter			IDLE = 2'b00,		SYNC = 2'b01,
					DATA_BEGIN = 2'b10,		DATA = 2'b11,
					TH_FOU_PERD = 6'd24;

assign quarter_bit = (cnt[4:0] == 5'd15) && car_L2H;
assign half_bit = (cnt[4:0] == 5'd31) && car_L2H;
//assign one_bit = (cnt == 6'd63) && car_L2H;
assign data = mode ? (cnt > TH_FOU_PERD) : (buff == 2'b01); 
assign en_sig = buff == 2'b11;
assign data_val = mode ? ((any_edge & stSYNC) | (any_edge & data & stDATA)):((cnt == 6'd32) && stDATA && car_L2H);
assign stSYNC = state == SYNC;
//assign stDATA_BEGIN = state == DATA_BEGIN;
assign stIDLE = state == IDLE;
assign stDATA = state == DATA;
assign dec_en = stDATA | mode | stIDLE;
assign cnt_clr = (quarter_bit & stSYNC & (~mode)) | (any_edge & mode);

/**********************state machine**********************/
always @(posedge clk_1m or negedge rst_n)
if(~rst_n)
	state <= IDLE;
else
	state <= nstate;

always @(*)
	case(state)
	IDLE: nstate = (oe & active & (~check_stage)) ? SYNC :IDLE;
	SYNC: nstate = oe ? (mode ? (any_edge ? DATA: SYNC):(quarter_bit ? DATA_BEGIN: SYNC)):IDLE;
	DATA_BEGIN: nstate = en_sig ? DATA: DATA_BEGIN;
	DATA: nstate = oe ? ((mode & any_edge) ? SYNC:DATA):IDLE;
	default: nstate = 2'bxx;
	endcase

/**********************buff*******************************/
always @(posedge clk_1m or negedge rst_n)
if(~rst_n)
	buff <= 2'b00;
else if(stIDLE)
	buff <= 2'b00;
else if(half_bit | (stSYNC & quarter_bit))
	buff <= {buff[0], rxd};

endmodule 
			
